//package info.wangyuan.agent.utils;
//
//import cn.hutool.core.collection.CollUtil;
//import dev.langchain4j.data.document.Document;
//import dev.langchain4j.data.document.loader.FileSystemDocumentLoader;
//import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
//import info.wangyuan.agent.entity.po.FileInfo;
//import info.wangyuan.agent.entity.po.KnowledgeBase;
//import info.wangyuan.agent.mapper.FileInfoMapper;
//import info.wangyuan.agent.mapper.KnowledgeBaseMapper;
//import info.wangyuan.agent.mapper.KnowledgeSourceMapper;
//import info.wangyuan.agent.service.VectorService;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component;
//
//import java.io.File;
//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.List;
//import java.util.Objects;
//
//import static info.wangyuan.agent.common.EmbeddingStoreConstant.*;
//import static info.wangyuan.agent.common.FileConstant.*;
//
///**
// * 文档元数据增强工具类
// * 功能：
// * 1. 重建知识库和文件信息
// * 2. 为 Document 添加元数据（knowledge_base, file_name）
// *
// * @author Albert
// * @since 2025-07-26 23:09:51
// */
//@Slf4j
//@Component
//public class DocumentMetadataEnhancer {
//
//    private final KnowledgeBaseMapper knowledgeBaseMapper;
//    private final KnowledgeSourceMapper knowledgeSourceMapper;
//    private final FileInfoMapper fileInfoMapper;
//    private final VectorService vectorService;
//    private final EmbeddingStoreIngestor ingestor;
//
//    public DocumentMetadataEnhancer(KnowledgeBaseMapper knowledgeBaseMapper, KnowledgeSourceMapper knowledgeSourceMapper, FileInfoMapper fileInfoMapper, VectorService vectorService, EmbeddingStoreIngestor ingestor) {
//        this.knowledgeBaseMapper = knowledgeBaseMapper;
//        this.knowledgeSourceMapper = knowledgeSourceMapper;
//        this.fileInfoMapper = fileInfoMapper;
//        this.vectorService = vectorService;
//        this.ingestor = ingestor;
//    }
//
//    /**
//     * 清空数据库和向量库
//     */
//    private void clearDatabasesAndVectors() {
//        log.info("清空表：tb_knowledge_base 和 tb_file_info");
//        knowledgeBaseMapper.truncateKnowledgeBase();
//        knowledgeSourceMapper.truncateKnowledgeSource();
//        fileInfoMapper.truncateFileInfo();
//        log.info("清空向量数据库");
//        vectorService.clearAllVectors();
//    }
//
//    /**
//     * 扫描根目录下的所有知识库目录，构建 KnowledgeBase 对象列表（未插入数据库）
//     */
//    private List<KnowledgeBase> scanKnowledgeBases(File root) {
//        if (!root.exists() || !root.isDirectory()) {
//            log.warn("ROOT_PATH [{}] 不存在或不是目录，跳过该知识库的重建。", RAG_ROOT_PATH);
//            return Collections.emptyList();
//        }
//
//        File[] kbDirs = root.listFiles(File::isDirectory);
//        if (kbDirs == null || kbDirs.length == 0) {
//            log.warn("ROOT_PATH [{}] 下未发现知识库目录", RAG_ROOT_PATH);
//            return Collections.emptyList();
//        }
//
//        List<KnowledgeBase> kbList = new ArrayList<>();
//
//        for (File kbDir : kbDirs) {
//            String kbName = kbDir.getName();
//            KnowledgeBase kb = KnowledgeBase.builder()
//                    .name(kbName)
//                    .path(kbDir.getAbsolutePath())
//                    .build();
//
//            kbList.add(kb);
//            log.info("发现知识库：{}", kbName);
//        }
//        return kbList;
//    }
//
//    /**
//     * 根据已插入且带有ID的KnowledgeBase加载文档，构建FileInfo列表
//     */
//    private List<FileInfo> buildFileInfosFromKnowledgeBases(List<KnowledgeBase> kbList, String rootPathCanonical) {
//        List<FileInfo> allFileInfos = new ArrayList<>();
//
//        for (KnowledgeBase kb : kbList) {
//            List<Document> docs = FileSystemDocumentLoader.loadDocumentsRecursively(
//                    kb.getPath(), PATH_MATCHER, DOC_PARSER);
//
//            DocumentMetadataEnhancer.addKnowledgeBaseMetadata(docs, rootPathCanonical);
//
//            List<FileInfo> fileInfos = docs.stream()
//                    .map(doc -> buildFileInfo(doc, kb))
//                    .filter(Objects::nonNull)
//                    .toList();
//
//            allFileInfos.addAll(fileInfos);
//        }
//        return allFileInfos;
//    }
//
//    /**
//     * 重建数据库和向量库：删除 -> 扫描 -> 插入KnowledgeBase -> 构建插入FileInfo -> 向量化导入文档
//     */
//    public void rebuildAllKnowledgeBases() {
//        log.info("========== 开始重建知识库与向量索引 ==========");
//        clearDatabasesAndVectors();
//
//        File root = new File(RAG_ROOT_PATH);
//        if (!root.exists() || !root.isDirectory()) {
//            log.warn("ROOT_PATH [{}] 不存在或不是目录，停止重建。", RAG_ROOT_PATH);
//            return;
//        }
//
//        // 1. 扫描目录，构建KnowledgeBase列表（无ID）
//        List<KnowledgeBase> kbList = scanKnowledgeBases(root);
//
//        if (CollUtil.isEmpty(kbList)) {
//            log.warn("未发现任何知识库目录，重建结束。");
//            return;
//        }
//
//        // 2. 批量插入KnowledgeBase，自动回填ID
//        kbList.forEach(knowledgeBaseMapper::insert);
//
//        // 3. 根据已插入的KnowledgeBase加载文档构造FileInfo列表
//        String rootPathCanonical = getCanonicalPath(root);
//        List<FileInfo> fileInfoList = buildFileInfosFromKnowledgeBases(kbList, rootPathCanonical);
//
//        // 4. 批量插入FileInfo
//        if (CollUtil.isNotEmpty(fileInfoList)) {
//            log.info("批量插入文件记录：{} 条", fileInfoList.size());
//            fileInfoList.forEach(fileInfoMapper::insert);
//        }
//
//        // 5. 向量化导入所有文档
//        List<Document> allDocs = new ArrayList<>();
//        for (KnowledgeBase kb : kbList) {
//            List<Document> docs = FileSystemDocumentLoader.loadDocumentsRecursively(
//                    kb.getPath(), PATH_MATCHER, DOC_PARSER);
//            DocumentMetadataEnhancer.addKnowledgeBaseMetadata(docs, rootPathCanonical);
//            allDocs.addAll(docs);
//        }
//
//        ingestDocuments(allDocs);
//
//        log.info("========== 重建完成：知识库 {} 个，文件 {} 个 ==========", kbList.size(), fileInfoList.size());
//    }
//
//    /**
//     * 确保文档 metadata 中存在 file_path，若缺失则用 absolute_directory_path + file_name 补全
//     */
//    private static String ensureFilePath(Document doc) {
//        String filePath = doc.metadata().getString("file_path");
//        if (filePath == null) {
//            String dir = doc.metadata().getString("absolute_directory_path");
//            String name = doc.metadata().getString("file_name");
//            if (dir != null && name != null) {
//                filePath = dir + File.separator + name;
//                doc.metadata().put("file_path", filePath);
//                log.warn("⚠️ [自动补全 file_path] {}", filePath);
//            } else {
//                log.error("❌ [无法补全 file_path] 缺少 absolute_directory_path 或 file_name: {}", doc);
//                return null;
//            }
//        }
//        return filePath;
//    }
//
//    /**
//     * 为文档添加元数据（知识库名称、文件名、file_path补全）
//     */
//    public static void addKnowledgeBaseMetadata(List<Document> documents, String rootPath) {
//        if (CollUtil.isEmpty(documents)) {
//            log.warn("文档列表为空，未执行元数据增强。");
//            return;
//        }
//        for (Document document : documents) {
//            String filePath = ensureFilePath(document);
//            if (filePath == null) continue;
//
//            File file = new File(filePath);
//            document.metadata().put(DOC_META_DATA_KB, extractKnowledgeBaseName(file, rootPath));
//            document.metadata().put(DOC_META_DATA_FN, file.getName());
//        }
//    }
//
//    /**
//     * 构建 FileInfo 对象
//     */
//    private FileInfo buildFileInfo(Document doc, KnowledgeBase kb) {
//        String filePath = ensureFilePath(doc);
//        if (filePath == null) {
//            log.error("❌ [无法创建 FileInfo] 文档缺少 file_path: {}", doc);
//            return null;
//        }
//        File file = new File(filePath);
//        return FileInfo.builder()
//                .name(file.getName())
//                .knowledgeBaseId(kb.getId())
//                .path(file.getAbsolutePath())
//                .size(file.length())
//                .suffix(file.getName().substring(file.getName().lastIndexOf(".") + 1))
//                .build();
//    }
//
//    /**
//     * 向量化导入文档
//     */
//    private void ingestDocuments(List<Document> docs) {
//        if (CollUtil.isEmpty(docs)) {
//            log.info("无文档可向量化。");
//            return;
//        }
//        log.info("开始向量化 {} 个文档...", docs.size());
//        ingestor.ingest(docs);
//        log.info("向量化完成。");
//    }
//
//    /**
//     * 提取知识库名
//     */
//    private static String extractKnowledgeBaseName(File file, String rootPath) {
//        try {
//            String canonicalRoot = new File(rootPath).getCanonicalPath();
//            File parentDir = file.getParentFile();
//            while (parentDir != null) {
//                String parentPath = parentDir.getCanonicalPath();
//                if (Objects.equals(parentPath, canonicalRoot)) return DEFAULT_DOC_META_DATA_KB;
//                if (Objects.equals(parentDir.getParentFile().getCanonicalPath(), canonicalRoot))
//                    return parentDir.getName();
//                parentDir = parentDir.getParentFile();
//            }
//        } catch (Exception e) {
//            log.error("提取文件 [{}] 的知识库名称失败：{}", file.getAbsolutePath(), e.getMessage());
//        }
//        return DEFAULT_DOC_META_DATA_KB;
//    }
//
//    /**
//     * 获取文件或目录的规范路径
//     */
//    private static String getCanonicalPath(File file) {
//        try {
//            return file.getCanonicalPath();
//        } catch (Exception e) {
//            return file.getAbsolutePath();
//        }
//    }
//}
